home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Human Interface Toolbox / ShowInitIcon / ShowInitIcon.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  6.7 KB  |  182 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ShowInitIcon.c
  3.  
  4.     Contains:    This code is intended to let INIT writers easily display an icon at startup time.
  5.                 
  6.                 This version features:
  7.                 - Short and readable code.
  8.                 - Correctly wraps around when more than one row of icons has been displayed.
  9.                 - works with System 6
  10.                 - Built with Universal Headers & CodeWarrior. Should work with other headers/compilers.
  11.  
  12.     Written by: Peter N Lewis, Jim Walker and François Pottier
  13.                     
  14.     Copyright:    Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved.
  15.  
  16.                 You may incorporate this Apple sample source code into your program(s) without
  17.                 restriction. This Apple sample source code has been provided "AS IS" and the
  18.                 responsibility for its operation is yours. You are not permitted to redistribute
  19.                 this Apple sample source code as "Apple sample source code" after having made
  20.                 changes. If you're going to re-distribute the source, we require that you make
  21.                 it clear in the source that the code was descended from Apple sample source
  22.                 code, but that you've made changes.
  23.  
  24.     Change History (most recent first):
  25.                 8/10/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  26.                 
  27.  
  28. */
  29. #include <Memory.h>
  30. #include <Resources.h>
  31. #include <Icons.h>
  32. #include <OSUtils.h>
  33. #include "ShowInitIcon.h"
  34.  
  35.  
  36.  
  37. // You should set SystemSixOrLater in your headers to avoid including glue for SysEnvirons.
  38.  
  39. // ---------------------------------------------------------------------------------------------------------------------
  40. // Set this flag to 1 if you want to compile this file into a stand-alone resource (see note below).
  41. // Set it to 0 if you want to include this source file into your INIT project.
  42.  
  43. #if 1
  44. #define ShowInitIcon main
  45. #ifdef powerc
  46.     //setup ___procinfo for Accelerated Resource
  47.     ProcInfoType __procinfo=kPascalStackBased
  48.             | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  49.              | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean)));
  50. #endif
  51. #endif
  52. // ---------------------------------------------------------------------------------------------------------------------
  53. // The ShowINIT mechanism works by having each INIT read/write data from these globals.
  54. // The MPW C compiler doesn't accept variables declared at an absolute address, so I use these macros instead.
  55. // Only one macro is defined per variable; there is no need to define a Set and a Get accessor like in <LowMem.h>.
  56.  
  57. #define    LMVCoord            (* (short*) 0x92A)
  58. #define    LMVCheckSum        (* (short*) 0x928)
  59. #define    LMHCoord            (* (short*) 0x92C)
  60. #define    LMHCheckSum        (* (short*) 0x92E)
  61.  
  62. // ---------------------------------------------------------------------------------------------------------------------
  63. // Prototypes for the subroutines. The main routine comes first; this is necessary to make THINK C's "Custom Header" option work.
  64.  
  65. static unsigned short CheckSum (unsigned short x);
  66. static void ComputeIconRect (Rect* iconRect, Rect* screenBounds);
  67. static void AdvanceIconPosition (Rect* iconRect);
  68. static void DrawBWIcon (short iconID, Rect *iconRect);
  69.  
  70. // ---------------------------------------------------------------------------------------------------------------------
  71. // Main routine.
  72.  
  73. typedef struct {
  74.     QDGlobals            qd;                                    // Storage for the QuickDraw globals
  75.     long                qdGlobalsPtr;                            // A5 points to this place; it will contain a pointer to qd
  76. } QDStorage;
  77.  
  78. pascal void ShowInitIcon (short iconFamilyID, Boolean advance)
  79. {
  80.     long                oldA5;                                // Original value of register A5
  81.     QDStorage            qds;                                    // Fake QD globals
  82.     CGrafPort            colorPort;
  83.     GrafPort            bwPort;
  84.     Rect                destRect;
  85.     SysEnvRec        environment;                            // Machine configuration.
  86.     
  87.     oldA5 = SetA5((long) &qds.qdGlobalsPtr);                        // Tell A5 to point to the end of the fake QD Globals
  88.     InitGraf(&qds.qd.thePort);                                // Initialize the fake QD Globals
  89.     
  90.     SysEnvirons(curSysEnvVers, &environment);                    // Find out what kind of machine this is
  91.  
  92.     ComputeIconRect(&destRect, &qds.qd.screenBits.bounds);            // Compute where the icon should be drawn
  93.  
  94.     if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
  95.         OpenCPort(&colorPort);
  96.         PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
  97.         CloseCPort(&colorPort);
  98.     }
  99.     else {
  100.         OpenPort(&bwPort);
  101.         DrawBWIcon(iconFamilyID, &destRect);
  102.         ClosePort(&bwPort);
  103.     }
  104.     
  105.     if (advance)
  106.         AdvanceIconPosition (&destRect);
  107.         
  108.     SetA5(oldA5);                                             // Restore A5 to its previous value
  109. }
  110.  
  111. // ---------------------------------------------------------------------------------------------------------------------
  112. // A checksum is used to make sure that the data in there was left by another ShowINIT-aware INIT.
  113.  
  114. static unsigned short CheckSum (unsigned short x)
  115. {
  116.     return ((x << 1) | (x >> 15)) ^ 0x1021;
  117. }
  118.  
  119. // ---------------------------------------------------------------------------------------------------------------------
  120. // ComputeIconRect computes where the icon should be displayed.
  121.  
  122. static void ComputeIconRect (Rect* iconRect, Rect* screenBounds)
  123. {
  124.     if (CheckSum(LMHCoord) != LMHCheckSum)                    // If we are first, we need to initialize the shared data.
  125.         LMHCoord = 8;
  126.     if (CheckSum(LMVCoord) != LMVCheckSum)
  127.         LMVCoord = screenBounds->bottom - 40;
  128.     
  129.     if (LMHCoord + 34 > screenBounds->right) {                    // Check whether we must wrap
  130.         iconRect->left = 8;
  131.         iconRect->top = LMVCoord - 40;
  132.     }
  133.     else {
  134.         iconRect->left = LMHCoord;
  135.         iconRect->top = LMVCoord;
  136.     }
  137.     iconRect->right = iconRect->left + 32;
  138.     iconRect->bottom = iconRect->top + 32;
  139. }
  140.  
  141. // AdvanceIconPosition updates the shared global variables so that the next extension will draw its icon beside ours.
  142.  
  143. static void AdvanceIconPosition (Rect* iconRect)
  144. {
  145.     LMHCoord = iconRect->left + 40;                            // Update the shared data
  146.     LMVCoord = iconRect->top;
  147.     LMHCheckSum = CheckSum(LMHCoord);
  148.     LMVCheckSum = CheckSum(LMVCoord);
  149. }
  150.  
  151. // DrawBWIcon draws the 'ICN#' member of the icon family. It works under System 6.
  152.  
  153. static void DrawBWIcon (short iconID, Rect *iconRect)
  154. {
  155.     Handle        icon;
  156.     BitMap        source, destination;
  157.     GrafPtr        port;
  158.     
  159.     icon = Get1Resource('ICN#', iconID);
  160.     if (icon != NULL) {
  161.         HLock(icon);
  162.                                                         // Prepare the source and destination bitmaps.
  163.         source.baseAddr = *icon + 128;                        // Mask address.
  164.         source.rowBytes = 4;
  165.         SetRect(&source.bounds, 0, 0, 32, 32);
  166.         GetPort(&port);
  167.         destination = port->portBits;
  168.                                                         // Transfer the mask.
  169.         CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
  170.                                                         // Then the icon.
  171.         source.baseAddr = *icon;
  172.         CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
  173.     }
  174. }
  175.  
  176. // ---------------------------------------------------------------------------------------------------------------------
  177. // Notes
  178.  
  179. // Checking for PlotIconID:
  180. // We (PNL) now check for system 7 and colour QD, and use colour graf ports and PlotIconID only if both are true
  181. // Otherwise we use B&W grafport and draw using PlotBWIcon.
  182.